package com.lingchen.controller;

import com.lingchen.response.Result;
import com.lingchen.response.ResultUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.Callable;

/**
 * Author    lingchen
 * Email     838878458@qq.com
 * Time      2018/5/14
 * Function  ...
 */
@Controller
@RequestMapping("test/")
public class TestController {
    private Logger log = Logger.getLogger(TestController.class);
    @Autowired
    private TestQueue testQueue;

    @RequestMapping(value = "add", method = RequestMethod.POST)
    @ResponseBody
    public Callable<Result<String>> add() {
        log.debug("请求时间1-->" + System.currentTimeMillis());

        Callable<Result<String>> callable = new Callable<Result<String>>() {
            public Result<String> call() throws Exception {
                log.debug("请求时间2-->" + System.currentTimeMillis());
                Thread.sleep(2000);
                log.debug("请求时间3-->" + System.currentTimeMillis());
                return ResultUtil.success();
            }
        };
        log.debug("请求时间4-->" + System.currentTimeMillis());
        return callable;
    }

    @RequestMapping(value = "add1", method = RequestMethod.POST)
    @ResponseBody
    public DeferredResult<Result<String>> add1() {
        log.debug("请求时间1-->" + System.currentTimeMillis());
        final DeferredResult<Result<String>> deferredResult = new DeferredResult<Result<String>>(1000L);
        deferredResult.onTimeout(new Runnable() {
            public void run() {
                log.debug("请求超时-->" + System.currentTimeMillis());
                deferredResult.setResult(ResultUtil.<String>success());
            }
        });
        dealInOtherThread(deferredResult);
        log.debug("请求时间3-->" + System.currentTimeMillis());
        return deferredResult;

    }

    @RequestMapping(value = "add2", method = RequestMethod.POST)
    @ResponseBody
    public DeferredResult<Result<String>> add2() {
        final DeferredResult<Result<String>> deferredResult = new DeferredResult<Result<String>>(3000L);
        deferredResult.onTimeout(new Runnable() {
            public void run() {
                log.debug("请求超时-->" + System.currentTimeMillis());
                deferredResult.setResult(ResultUtil.<String>success());
            }
        });
        testQueue.start();
        start();
        return deferredResult;

    }

    private void start(){
        for (int i = 0; i < 20; i++) {
            new Thread(new Runnable() {
                public void run() {
                    final DeferredResult<Result<String>> deferredResult = new DeferredResult<Result<String>>(3000L);
                    deferredResult.onTimeout(new Runnable() {
                        public void run() {
                            log.debug("请求超时-->" + System.currentTimeMillis());
                            deferredResult.setResult(ResultUtil.<String>success());
                        }
                    });
                    if (testQueue.offer(deferredResult)) {
                        log.debug("任务添加成功-->");
                    } else {
                        log.debug("任务添加失败-->");
                    }
                }
            }).start();
        }
    }


    private void dealInOtherThread(final DeferredResult<Result<String>> deferredResult) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    log.debug("请求时间2-->" + System.currentTimeMillis());
                    deferredResult.setResult(ResultUtil.<String>success());
                }
            }
        }).start();
    }
}
